package top.yqingyu.trans$client.cs.command.impl;


import top.yqingyu.common.function.Progress;
import top.yqingyu.common.qydata.DataMap;
import top.yqingyu.common.utils.IoUtil;
import top.yqingyu.common.utils.ThreadUtil;
import top.yqingyu.common.utils.UUIDUtil;
import top.yqingyu.qymsg.MsgHelper;
import top.yqingyu.qymsg.QyMsg;
import top.yqingyu.qymsg.bean.TransObj;
import top.yqingyu.trans$client.api.Connection;
import top.yqingyu.trans$client.common.TransChannel;
import top.yqingyu.trans$client.cs.command.Command;
import top.yqingyu.trans$client.main.TransClient;

import java.io.File;
import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author YYJ
 * @version 1.0.0

 */
public class Upload extends Command {
    private static final String commandRegx = "[Uu]pload.*";
    private static final ThreadPoolExecutor executor = ThreadUtil.createQyFixedThreadPool(10, 10, 1800, "UPLOAD", "t");

    @Override
    public void dealCommand(TransClient client, Connection conn, QyMsg msg) throws Exception {
        dealWrite(client, conn, msg);
    }

    @Override
    public void deal(QyMsg msg, TransClient client) throws Exception {
        DataMap dataMap = msg.getDataMap();
        ArrayList<TransObj> transObjs = new ArrayList<>();
        if ("API".equals(System.getProperty(client.clientConf.CLIENT_USER_ID))) {
            msg.putMsg("upload");
            List<File> list = dataMap.getList("upload", File.class);
            List<Progress> uploadProgress = dataMap.getList("uploadProgress", Progress.class);
            dataMap.remove("uploadProgress");
            String s = UUIDUtil.randomUUID().toString();
            for (int i = 0; i < list.size(); i++) {
                File file = list.get(i);
                Progress progress = uploadProgress.get(i);
                TransObj transObj = new TransObj(s);
                transObjs.add(transObj);
                transObj.setFileName(file.getName());
                transObj.setSendPath(file.getAbsolutePath());
                transObj.setUpload(true);
                s = UUIDUtil.randomUUID().toString();
                transObj.setNextId(s);
                transObj.setSize(file.length());
                transObj.setProgress(progress);
            }
        } else {
            String str = MsgHelper.gainMsg(msg);
            msg.putMsg("upload");
            String[] split = str.split(" {1,4}");
            String local = split[1];
            File file = new File(local);
            if (!file.exists()) {
                return;
            }
            TransObj transObj = new TransObj(UUIDUtil.randomUUID().toString());
            transObjs.add(transObj);
            transObj.setSendPath(file.getAbsolutePath());
            transObj.setFileName(file.getName());
            transObj.setSize(file.length());
            transObj.setUpload(true);
        }
        msg.putMsgData("upload", transObjs);
        if (!transObjs.isEmpty()) {
            executor.execute(getThread(client, transObjs));
        }

    }

    private static Thread getThread(TransClient client, ArrayList<TransObj> transObjs) {
        Thread thread = new Thread(() -> {
            SocketChannel socket = null;
            try {
                Thread.sleep(1500);
                socket = TransChannel.getTransChannel(client, client.clientConf.HOST, client.clientConf.PORT3, "upload");
                for (TransObj transObj : transObjs) {
                    String fileId = transObj.getFileId();
                    client.clientConf.msgTransfer.writeMessage(socket, fileId);
                    IoUtil.writeFile(new File(transObj.getSendPath()), socket, transObj.getProgress());
                }
            } catch (Exception e) {
                try {
                    if (socket != null)
                        socket.close();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                throw new RuntimeException(e);
            }
        });
        thread.setName("upload");
        return thread;
    }
}
